﻿using JESAI.DistributedLock.Internal;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace JESAI.DistributedLock.ZooKeeper;

/// <summary>
/// 实现 <see cref="IDistributedSynchronizationHandle"/>
/// </summary>
public sealed class ZooKeeperDistributedSemaphoreHandle : IDistributedSynchronizationHandle
{
    private ZooKeeperNodeHandle? _innerHandle;
    private IDisposable? _finalizerRegistration;

    internal ZooKeeperDistributedSemaphoreHandle(ZooKeeperNodeHandle innerHandle)
    {
        this._innerHandle = innerHandle;
        // /如果进程退出，我们使用临时节点的事实为我们提供了有保证的放弃保护。不过，在那之前，我们很容易被抛弃，因为我们汇集了ZooKeeper会话。
        // 虽然这些会话有一个最大期限，但只要它们的句柄保持打开状态，它们就无法退出
        this._finalizerRegistration = ManagedFinalizerQueue.Instance.Register(this, innerHandle);
    }

    /// <summary>
    /// 实现 <see cref="IDistributedSynchronizationHandle.HandleLostToken"/>
    /// </summary>
    public CancellationToken HandleLostToken => (Volatile.Read(ref this._innerHandle) ?? throw this.ObjectDisposed()).HandleLostToken;

    //显式，因为这是异步同步
    void IDisposable.Dispose() => this.DisposeSyncViaAsync();

    /// <summary>
    /// 释放信号量
    /// </summary>
    public ValueTask DisposeAsync()
    {
        Interlocked.Exchange(ref this._finalizerRegistration, null)?.Dispose();
        return Interlocked.Exchange(ref this._innerHandle, null)?.DisposeAsync() ?? default;
    }
}
